package com.universal.frame.appupdate;

import java.io.File;
import java.io.IOException;

import com.universal.frame.R;
import com.universal.frame.generalutils.ApkUtil;
import com.universal.frame.generalutils.Constants;
import com.universal.frame.generalutils.FileUtils;
import com.universal.frame.generalutils.GeneralUtil;
import com.universal.frame.generalutils.SharedPreferencesUtil;
import com.universal.frame.okhttp.OKHttpUtils;
import okhttp3.Request;
import okhttp3.Response;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;


public class UpdateAppService extends IntentService {

    private String TAG = "UpdateAppService";


    private NotificationManager mNotificationManager;
    private NotificationCompat.Builder mBuilder;
    private int notifyId = 102;

    private static final int BUFFER_SIZE = 10 * 1024; // 8k ~ 32K

    public UpdateAppService() {
        super("UpdateAppService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        initNotify();

        String urlStr = intent.getStringExtra(Constants.ACTIVITY_PUTEXTRA_APK_URL);
        String version = intent.getStringExtra(Constants.ACTIVITY_PUTEXTRA_APK_VERSION);
        ;
        String currentVersion = ApkUtil.getAppVersionName(this);

        Log.i("taglv_tag", "urlStr = " + urlStr);

        if (FileUtils.isFileExist(GeneralUtil.getAPKSaveFilePath(this, currentVersion))) {
            FileUtils.deleteFile(GeneralUtil.getAPKSaveFilePath(this, currentVersion));
        }

        BufferedSource bufferedSource = null;
        BufferedSink bufferedSink = null;

        try {

            Request request = new Request.Builder().url(urlStr).build();
            Response response = OKHttpUtils.getInstance().getHttpClient().newCall(request).execute();

            if (response.isSuccessful()) {
                if (!FileUtils.isFileExist(GeneralUtil.getAPKSaveFilePath(this, version))) {
                    FileUtils.makeDirs(GeneralUtil.getAPKSaveFilePath(this, version));
                }

                File apkFile = new File(GeneralUtil.getAPKSaveFilePath(this, version));    //文件存放位置

                long byteTotal = response.body().contentLength();    //文件大小
                SharedPreferencesUtil.putString(this, Constants.SP_FIELD_APP_FILE_SIZE, String.valueOf(byteTotal));

                byte[] buffer = new byte[BUFFER_SIZE];    //文件缓冲区大小
                int byteLen = 0;    //当前文件大小
                long byteSum = 0;    //已读文件大小

                int oldProgress = 0;

                bufferedSource = Okio.buffer(response.body().source());
                bufferedSink = Okio.buffer(Okio.sink(apkFile));

                while ((byteLen = bufferedSource.read(buffer)) != -1) {
                    byteSum += byteLen;
                    bufferedSink.write(buffer, 0, byteLen);
                    int progress = (int) (byteSum * 100L / byteTotal);
                    // 如果进度与之前进度相等，则不更新，如果更新太频繁，否则会造成界面卡顿
                    if (progress != oldProgress) {
                        updateProgress(progress);
                    }
                    oldProgress = progress;
                }

                installApk(apkFile);
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            if (bufferedSink != null) {
                try {
                    bufferedSink.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedSource != null) {
                try {
                    bufferedSource.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 初始化通知栏
     */
    private void initNotify() {

        PendingIntent pendingintent = PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_CANCEL_CURRENT);

        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mBuilder = new NotificationCompat.Builder(this);
        mBuilder.setWhen(System.currentTimeMillis())    // 通知产生的时间，会在通知信息里显示
                .setContentIntent(pendingintent)
                .setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级
                .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.app_icon))
                // .setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消
                .setOngoing(false)// ture，设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
                // 向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置，使用defaults属性，可以组合：
                // Notification.DEFAULT_ALL Notification.DEFAULT_SOUND 添加声音 //
                // requires VIBRATE permission
                .setSmallIcon(R.mipmap.app_icon);

    }


    private void updateProgress(int progress) {
        mBuilder.setContentTitle(getString(R.string.text_app_update_downloading))
                .setContentText(getString(R.string.text_app_update_current_progress) + progress + "%")
                .setTicker(getString(R.string.text_app_update_downloading))
                .setProgress(100, progress, false);
        //setContentInent如果不设置在4.0+上没有问题，在4.0以下会报异常
        PendingIntent pendingintent = PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_CANCEL_CURRENT);
        mBuilder.setContentIntent(pendingintent);
        mNotificationManager.notify(notifyId, mBuilder.build());
    }

    private void installApk(File apkFile) throws Exception {
        // 下载完成
        mBuilder.setContentTitle(getString(R.string.text_app_update_downloading_success))
                .setContentText(getString(R.string.text_app_update_downloading_success))
                .setProgress(100, 100, false);

        // 如果没有设置SDCard写权限，或者没有sdcard,apk文件保存在内存中，需要授予权限才能安装
        String[] command = {"chmod", "777", apkFile.toString()};
        ProcessBuilder builder = new ProcessBuilder(command);
        builder.start();

        Intent intent = new Intent(Intent.ACTION_VIEW);
        //判断是否是AndroidN以及更高的版本
        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {
            Uri contentUri = FileProvider.getUriForFile(this,"com.jy.ylzs.fileProvider",apkFile);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(contentUri,"application/vnd.android.package-archive");
        }else{
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
        }
        startActivity(intent);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(pendingIntent);
        Notification noti = mBuilder.build();
        noti.flags = Notification.FLAG_AUTO_CANCEL;
        mNotificationManager.notify(notifyId, noti);
        mNotificationManager.cancel(notifyId);
    }

}
